home *** CD-ROM | disk | FTP | other *** search
- /* convers server - based on conversd written by DK5SG
- * ported to WNOS by DB3FL - 9109xx/9110xx
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #ifdef UNIX
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
- #include <io.h>
- #include "global.h"
- #include "config.h"
- #ifdef CONVERS
- #ifdef MAILBOX
- #include "mailbox.h"
- #include "netuser.h"
- #endif
- #include "timer.h"
- #include "smtp.h"
- #include "cmdparse.h"
- #include "socket.h"
- #include "session.h"
- #include "files.h"
- #ifdef LZW
- #include "lzw.h"
- #endif
-
- #define LINK 1
-
- #ifdef LINK
- static struct proc *child = NULLPROC;
- static void connect_permlinks __ARGS((int a, void *b, void *c));
- #endif
-
- static void conv_incom __ARGS((int s, void *t, void *p));
- static char * near getarg __ARGS((char *line, int all));
-
- static int Sconv = -1;
- #ifdef LZW
- static int Sxconv = -1;
- #endif
-
- static char *myhostname = NULLCHAR;
- static char cnumber[] = "*** Channel numbers must be in the range 0..%d.\n";
-
- #define MAXCHANNEL 32766
- #define LINELEN 256
- #define CBUFLEN 2048
- #define MAX_WAITTIME (60*60*3)
-
- struct convection {
- int type; /* Connection type */
- #define CT_UNKNOWN 0
- #define CT_USER 1
- #define CT_HOST 2
- #define CT_CLOSED 3
- char name[80]; /* Name of user or host */
- char host[80]; /* Name of host where user is logged on */
- struct convection *via; /* Pointer to neighbor host */
- int channel; /* Channel number */
- int32 time; /* Connect time */
- int locked; /* Set if mesg already sent */
- int fd; /* Socket descriptor */
- int fmask; /* Socket mask */
- char *ibuf; /* Input buffer */
- int received; /* Number of bytes received */
- int xmitted; /* Number of bytes transmitted */
- struct convection *next; /* Linked list pointer */
- };
-
- #define CM_UNKNOWN (1 << CT_UNKNOWN)
- #define CM_USER (1 << CT_USER)
- #define CM_HOST (1 << CT_HOST)
- #define CM_CLOSED (1 << CT_CLOSED)
-
- #define NULLCONNECTION ((struct convection *) 0)
-
- static struct convection *convections;
-
- struct permlink {
- char name[80]; /* Name of host */
- char link_info[80]; /* Name of socket to connect to */
- char command[80]; /* Optional connect command */
- struct convection *convection;/* Pointer to associated connection */
- int32 statetime; /* Time of last (dis)connect */
- int tries; /* Number of connect tries */
- int32 waittime; /* Time between connect tries */
- int32 retrytime; /* Time of next connect try */
- int fd; /* socket descriptor */
- struct permlink *next; /* Linked list pointer */
- };
- #define NULLPERMLINK ((struct permlink *) 0)
-
- static struct permlink *permlinks;
-
- static struct convection * near alloc_connection __ARGS((int fd));
- static char * near getarg __ARGS((char *line, int all));
- static char * near timestring __ARGS((int32 gmt));
- static void near free_connection __ARGS((struct convection *cp));
- static char * formatline __ARGS((char *prefix,char *text));
- static void near clear_locks __ARGS((void));
- static void send_msg_to_user __ARGS((char *fromname,char *toname,char *text));
- static void send_msg_to_channel __ARGS((char *fromname,int channel,char *text));
- static void near update_permlinks __ARGS((char *name,struct convection *cp));
- static void send_user_change_msg __ARGS((char *name,char *host,int oldchannel,int newchannel));
- static void bye_command __ARGS((struct convection *cp));
- static void send_invite_msg __ARGS((char *fromname,char *toname,int channel));
- static void near free_closed_connections __ARGS((void));
-
- /* Stop convers server */
- int
- conv0(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- #ifdef LINK
- #ifdef LZW
- if(Sxconv == -1) {
- killproc(child);
- child = NULLPROC;
- }
- #else
- killproc(child);
- child = NULLPROC;
- #endif
- #endif
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
-
- #ifdef LZW
- /* Stop xconvers server */
- int
- xconv0(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- #ifdef LINK
- if(Sconv == -1) {
- killproc(child);
- child = NULLPROC;
- }
- #endif
- close_s(Sxconv);
- Sxconv = -1;
- return 0;
- }
- #endif
-
- /* Start up convers server */
- int
- conv1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in lsocket;
- int s;
-
- if(Sconv != -1)
- return 0;
-
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"Convers listener");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = (argc < 2) ? IPPORT_CONVERS : atoi(argv[1]);
-
- Sconv = socket(AF_INET,SOCK_STREAM,0);
- bind(Sconv,(char *)&lsocket,sizeof(lsocket));
- listen(Sconv,1);
- #ifdef LINK
- if(child == NULLPROC)
- child = newproc("cperm",1024,connect_permlinks,0,0,NULL,0);
- #else
- myhostname = strxdup(Hostname);
- #endif
- for(;;){
- if((s = accept(Sconv,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
-
- if(availmem() < Memthresh){
- shutdown(s,1);
- } else {
- /* Spawn a server */
- newproc("conversd",2048,conv_incom,s,0,NULL,0);
- }
- }
- return 0;
- }
-
- #ifdef LZW
- /* Start up xconvers server */
- int
- xconv1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in lsocket;
- int s;
-
- if(Sxconv != -1)
- return 0;
-
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"XConv listener");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = (argc < 2) ? IPPORT_XCONVERS : atoi(argv[1]);
-
- Sxconv = socket(AF_INET,SOCK_STREAM,0);
- bind(Sxconv,(char *)&lsocket,sizeof(lsocket));
- listen(Sxconv,1);
- #ifdef LINK
- if(child == NULLPROC)
- child = newproc("cperm",1024,connect_permlinks,0,0,NULL,0);
- #else
- myhostname = strxdup(Hostname);
- #endif
- for(;;){
- if((s = accept(Sxconv,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
-
- if(availmem() < Memthresh){
- shutdown(s,1);
- } else {
- /* Spawn a server */
- newproc("xconversd",2048,conv_incom,s,(void *)1,NULL,0);
- }
- }
- return 0;
- }
- #endif
-
- static char * near
- getarg(line, all)
- char *line;
- int all;
- {
- char *arg;
- int c;
- static char *p;
-
- if (line) p = line;
- while (isspace(uchar(*p))) p++;
- if (all) return p;
- arg = p;
- while (*p && !isspace(uchar(*p))) {
- c = tolower(uchar(*p));
- *p++ = c;
- }
- if (*p) *p++ = '\0';
- return arg;
- }
-
- static void near
- free_connection(cp)
- struct convection *cp;
- {
- struct permlink *p;
-
- for (p = permlinks; p; p = p->next)
- if (p->convection == cp) p->convection = NULLCONNECTION;
- if (cp->fmask) close_s(cp->fd);
- xfree(cp->ibuf);
- xfree((char *)cp);
- }
-
- static void near
- free_closed_connections()
- {
- struct convection *cp, *p;
-
- for (p = NULLCONNECTION, cp = convections; cp; )
- if (cp->type == CT_CLOSED ||
- cp->type == CT_UNKNOWN && cp->time + 300 < currtime) {
- if (p) {
- p->next = cp->next;
- free_connection(cp);
- cp = p->next;
- } else {
- convections = cp->next;
- free_connection(cp);
- cp = convections;
- }
- } else {
- p = cp;
- cp = cp->next;
- }
- }
-
- static void near
- update_permlinks(name, cp)
- char *name;
- struct convection *cp;
- {
- struct permlink *p;
-
- for (p = permlinks; p; p = p->next)
- if (!strcmp(p->name, name)) {
- p->convection = cp;
- p->statetime = currtime;
- p->tries = 0;
- p->waittime = 60;
- p->retrytime = currtime + p->waittime;
- }
- }
-
- static struct convection * near
- alloc_connection(fd)
- int fd;
- {
- struct convection *cp =
- (struct convection *)mxallocw(sizeof(struct convection));
-
- cp->fd = cp->fmask = fd;
- cp->time = currtime;
- cp->next = convections;
- cp->ibuf = mxallocw(CBUFLEN);
- convections = cp;
- return cp;
- }
-
- #ifdef LINK
- void
- connect_permlinks(a,b,c)
- int a;
- void *b;
- void *c;
- {
- int s, x, len = SOCKSIZE;
- struct permlink *p;
- struct sockaddr_in cport;
- FILE *fp;
- char *host_name, *link_info, *command, line[LINELEN];
-
- if ((fp = fopen(Convers,"r")) == NULLFILE) {
- if(myhostname == NULLCHAR) {
- myhostname = strxdup(Hostname);
- }
- } else {
- while (fgets(line, LINELEN, fp)) {
- rip(line);
- if(*line == '#' || *line == '\0') continue;
- host_name = getarg(line,0);
- link_info = getarg(0,0);
- command = getarg(0,0);
-
- if(host_name == NULLCHAR) continue;
-
- if (myhostname == NULLCHAR) {
- myhostname = strxdup(host_name);
- continue;
- }
- if (link_info != NULLCHAR) {
- p = (struct permlink *)mxallocw(sizeof(struct permlink));
- sprintf(p->name,"%.79s",host_name);
- sprintf(p->link_info,"%.79s",link_info);
- if(command != NULLCHAR)
- sprintf(p->command,"%.79s",command);
- p->next = permlinks;
- permlinks = p;
- update_permlinks(host_name, NULLCONNECTION);
- }
- }
- fclose(fp);
- }
-
- for(;;) {
- pause(1000L);
- for (p = permlinks; p; p = p->next) {
- if (p->convection || p->retrytime > currtime) continue;
- p->tries++;
- p->waittime <<= 1;
- if (p->waittime > MAX_WAITTIME) p->waittime = MAX_WAITTIME;
- p->retrytime = p->waittime + currtime;
- x = 0;
- switch(tolower(*p->link_info)) {
- case 'x': /* compressed telnet connection */
- x = 1;
- case 't': /* telnet connection */
- cport.sin_family = AF_INET;
- cport.sin_port = x ? IPPORT_XCONVERS : IPPORT_CONVERS;
- if((cport.sin_addr.s_addr = resolve(p->name)) != 0) {
- if((s = socket(AF_INET,SOCK_STREAM,0)) != -1) {
- if(connect(s,(char *)&cport,len) != -1) {
- p->fd = s;
- newproc("permlink",2048,conv_incom,s,(void *)x,NULL,0);
- } else {
- close_s(s);
- }
- }
- }
- break;
-
- /* case 'a': /* ax25 connection */
- /* case 'n': /* netrom connection */
- /* default: */
- /* continue; */
- }
- }
- }
- }
- #endif
-
-
- static void near
- clear_locks()
- {
- struct convection *p;
-
- for (p = convections; p; p = p->next) p->locked = 0;
- }
-
- static void
- send_user_change_msg(name, host, oldchannel, newchannel)
- char *name, *host;
- int oldchannel, newchannel;
- {
- struct convection *p;
-
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !p->via && !p->locked) {
- if (p->channel == oldchannel) {
- if (newchannel >= 0)
- p->xmitted += usprintf(p->fd, "*** %s switched to channel %d.\n", name, newchannel);
- else
- p->xmitted += usprintf(p->fd, "*** %s signed off.\n", name);
- p->locked = 1;
- }
- if (p->channel == newchannel) {
- p->xmitted += usprintf(p->fd, "*** %s signed on.\7\n", name);
- p->locked = 1;
- }
- }
- if (p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200USER %s %s 0 %d %d\n",
- name, host, oldchannel, newchannel);
- p->locked = 1;
- }
- }
- return;
- }
-
- static char *
- formatline(prefix, text)
- char *prefix, *text;
- {
-
- #define PREFIXLEN 10
- #define CONVLINELEN 79
-
- char *f, *t, *x;
- int l, lw;
- static char buf[2048];
-
- for (f = prefix, t = buf; *f; *t++ = *f++) ;
- l = (int)(t - buf);
- f = text;
-
- for (; ; ) {
- while (isspace(uchar(*f))) f++;
- if (!*f) {
- *t++ = '\n';
- *t = '\0';
- return buf;
- }
- for (x = f; *x && !isspace(uchar(*x)); x++) ;
- lw = (int)(x - f);
- if (l > PREFIXLEN && l + 1 + lw > CONVLINELEN) {
- *t++ = '\n';
- l = 0;
- }
- do {
- *t++ = ' ';
- l++;
- } while (l < PREFIXLEN);
- while (lw--) {
- *t++ = *f++;
- l++;
- }
- }
- }
-
- static void
- send_msg_to_user(fromname, toname, text)
- char *fromname, *toname, *text;
- {
- struct convection *p;
- char *buffer = mxallocw(CBUFLEN);
-
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !strcmp(p->name, toname))
- if (p->via) {
- if (!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200UMSG %s %s %s\n", fromname, toname, text);
- p->via->locked = 1;
- }
- } else {
- if (!p->locked) {
- if (strcmp(fromname, "conversd")) {
- sprintf(buffer, "<*%s*>:", fromname);
- p->xmitted += usprintf(p->fd,"%s",formatline(buffer, text));
- } else {
- p->xmitted += usprintf(p->fd,"%s\n",text);
- }
- p->locked = 1;
- }
- }
- }
- xfree(buffer);
- return;
- }
-
- static void
- send_msg_to_channel(fromname, channel, text)
- char *fromname;
- int channel;
- char *text;
- {
- struct convection *p;
- char *buffer = mxallocw(CBUFLEN);
-
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && p->channel == channel)
- if (p->via) {
- if (!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200CMSG %s %d %s\n", fromname, channel, text);
- p->via->locked = 1;
- }
- } else {
- if (!p->locked) {
- sprintf(buffer, "<%s>:", fromname);
- p->xmitted += usprintf(p->fd,"%s",formatline(&buffer[0],text));
- p->locked = 1;
- }
- }
- }
- xfree(buffer);
- return;
- }
-
- static char * near
- timestring(gmt)
- int32 gmt;
- {
- static char buffer[10];
- struct tm *tm = localtime(&gmt);
-
- if (gmt + 24 * 60 * 60 > currtime)
- sprintf(buffer, " %2d:%02d", tm->tm_hour, tm->tm_min);
- else
- sprintf(buffer, "%-3.3s %2d", Months[tm->tm_mon - 1], tm->tm_mday);
-
- return buffer;
- }
-
- static void
- send_invite_msg(fromname, toname, channel)
- char *fromname, *toname;
- int channel;
- {
- char invitetext[] = "\n\007\007*** Message from %s at%s ...\nPlease join convers channel %d.\n\007\007\n";
- char responsetext[] = "*** Invitation sent to %s @ %s";
- char cnvd[] = "conversd";
-
- char *buffer = mxallocw(CBUFLEN);
-
- struct convection *p;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
-
- for (p = convections; p; p = p->next) {
- #ifdef MAILBOX
- for (i = 0; i < NUMMBX; i++){
- if((m = Mbox[i]) != NULLMBX){
- if(m->state == MBX_CMD && !strcmp(m->name,toname)) {
- p->xmitted += usprintf(m->user, invitetext, fromname, timestring(currtime), channel);
- usflush(m->user);
- clear_locks();
- sprintf(buffer, responsetext, toname, "LocBBS@");
- strcat(buffer,Hostname);
- send_msg_to_user(cnvd, fromname, buffer);
- xfree(buffer);
- return;
- }
- }
- }
- #endif
- if (p->type == CT_USER && !strcmp(p->name, toname)) {
- if (p->channel == channel) {
- clear_locks();
- sprintf(buffer, "*** User %s is already on this channel.", toname);
- send_msg_to_user(cnvd, fromname, buffer);
- xfree(buffer);
- return;
- }
- if (!p->via && !p->locked) {
- p->xmitted += usprintf(p->fd, invitetext, fromname, timestring(currtime), channel);
- clear_locks();
- sprintf(buffer, responsetext, toname, myhostname);
- send_msg_to_user(cnvd, fromname, buffer);
- xfree(buffer);
- return;
- }
- if (p->via && !p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200INVI %s %s %d\n", fromname, toname, channel);
- xfree(buffer);
- return;
- }
- }
- }
- for (p = convections; p; p = p->next) {
- if (p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200INVI %s %s %d\n", fromname, toname, channel);
- }
- }
- xfree(buffer);
- return;
- }
-
- static void
- bye_command(cp)
- struct convection *cp;
- {
- struct convection *p;
-
- switch (cp->type) {
- case CT_UNKNOWN:
- cp->type = CT_CLOSED;
- break;
- case CT_USER:
- cp->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(cp->name, cp->host, cp->channel, -1);
- break;
- case CT_HOST:
- cp->type = CT_CLOSED;
- update_permlinks(cp->name, NULLCONNECTION);
- for (p = convections; p; p = p->next)
- if (p->via == cp) {
- p->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(p->name, p->host, p->channel, -1);
- }
- break;
- case CT_CLOSED:
- break;
- }
- }
-
- static void
- channel_command(cp)
- struct convection *cp;
- {
- int newchannel;
-
- char *s = getarg(0,0);
-
- if (!*s) {
- cp->xmitted += usprintf(cp->fd,"*** You are on channel %d.\n",cp->channel);
- return;
- }
- newchannel = atoi(s);
- if (newchannel < 0 || newchannel > MAXCHANNEL) {
- cp->xmitted += usprintf(cp->fd,cnumber,MAXCHANNEL);
- return;
- }
- if (newchannel == cp->channel) {
- cp->xmitted += usprintf(cp->fd,
- "*** Already on channel %d.\n", cp->channel);
- return;
- }
- send_user_change_msg(cp->name, cp->host, cp->channel, newchannel);
- cp->channel = newchannel;
- cp->xmitted += usprintf(cp->fd, "*** Now on channel %d.\n", cp->channel);
- return;
- }
-
- static void
- help_command(cp)
- struct convection *cp;
- {
- cp->xmitted += usputs(cp->fd, "Commands may be abbreviated. Commands are:\n");
- cp->xmitted += usputs(cp->fd, "/? Print help information\n");
- cp->xmitted += usputs(cp->fd, "/BYE Terminate the convers session\n");
- cp->xmitted += usputs(cp->fd, "/CHANNEL n Switch to channel n\n");
- cp->xmitted += usputs(cp->fd, "/EXIT Terminate the convers session\n");
- cp->xmitted += usputs(cp->fd, "/HELP Print help information\n");
- cp->xmitted += usputs(cp->fd, "/INVITE user Invite user to join your channel\n");
- cp->xmitted += usputs(cp->fd, "/LINKS [LONG] List all connections to other hosts\n");
- cp->xmitted += usputs(cp->fd, "/MSG user text... Send a private message to user\n");
- cp->xmitted += usputs(cp->fd, "/QUIT Terminate the convers session\n");
- cp->xmitted += usputs(cp->fd, "/WHO [QUICK] [LONG] List all users and their channel numbers\n");
- cp->xmitted += usputs(cp->fd, "/WRITE user text... Send a private message to user\n***\n");
- return;
- }
-
- static void
- invite_command(cp)
- struct convection *cp;
- {
- char *toname = getarg(0,0);
-
- if (*toname) send_invite_msg(cp->name, toname, cp->channel);
- }
-
- static void
- links_command(cp)
- struct convection *cp;
- {
- char tmp[20];
- struct convection *pc;
- struct permlink *pp;
-
- int full = *(getarg(0,0));
-
- cp->xmitted += usprintf(cp->fd,"Host State Since%s\n",
- full ? " NextTry Tries Queue Receivd Xmitted" : "");
- for (pc = convections; pc; pc = pc->next)
- if (pc->type == CT_HOST) {
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-8.8s %-12s %s%15d %7d %7d\n" :
- "%-8.8s %-12s %s\n",
- pc->name,
- "Connected",
- timestring(pc->time),
- 0, /* always 0, cuz NOS handles the tx-queue */
- pc->received,
- pc->xmitted);
- }
- for (pp = permlinks; pp; pp = pp->next)
- if (!pp->convection || pp->convection->type != CT_HOST) {
- strcpy(tmp, timestring(pp->retrytime)),
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-8.8s %-12s %s %s %5d\n" :
- "%-8.8s %-12s %s\n",
- pp->name,
- pp->convection ? "Connecting" : "Disconnected",
- timestring(pp->statetime),
- tmp,
- pp->tries);
- }
- cp->xmitted += usputs(cp->fd,"***\n");
- return;
- }
-
- static void
- msg_command(cp)
- struct convection *cp;
- {
-
- struct convection *p;
-
- char *toname = getarg(0,0);
- char *text = getarg(0,1);
-
- if (!*text) return;
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER && !strcmp(p->name, toname))
- break;
- if (!p)
- cp->xmitted += usprintf(cp->fd, "*** No such user: %s.\n", toname);
- else
- send_msg_to_user(cp->name, toname, text);
- return;
- }
-
- static void
- name_command(cp)
- struct convection *cp;
- {
- int newchannel;
-
- char *s = getarg(0,0);
- if(!*s)
- return;
- sprintf(cp->name,"%.79s",s);
- strlwr(cp->name);
- cp->type = CT_USER;
- sprintf(cp->host,"%.79s",myhostname);
- cp->xmitted += usprintf(cp->fd,
- "conversd @ %s $WNOS_Rev: B(2.17) $ Type /HELP for help.\n", myhostname);
-
- newchannel = atoi(getarg(0,0));
-
- if (newchannel < 0 || newchannel > MAXCHANNEL) {
- cp->xmitted += usprintf(cp->fd,cnumber,MAXCHANNEL);
- } else
- cp->channel = newchannel;
- send_user_change_msg(cp->name, cp->host, -1, cp->channel);
- return;
- }
-
- static void
- who_command(cp)
- struct convection *cp;
- {
-
- int channel, full = 0, quick = 0;
- struct convection *p;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
-
- char *buffer = mxallocw(CBUFLEN);
-
- switch(*(getarg(0,0))) {
- case 'l':
- full = 1;
- break;
- case 'q':
- quick = 1;
- break;
- }
-
- if (quick) {
- cp->xmitted += usprintf(cp->fd, "Channel Users\n");
- clear_locks();
- do {
- channel = -1;
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !p->locked && (channel < 0 || channel == p->channel)) {
- if (channel < 0) {
- channel = p->channel;
- sprintf(buffer, "%7d", channel);
- }
- strcat(buffer, " ");
- strcat(buffer, p->name);
- p->locked = 1;
- }
- }
- if (channel >= 0) {
- cp->xmitted += usprintf(cp->fd, "%s\n",buffer);
- }
- } while (channel >= 0);
- } else {
- cp->xmitted += usprintf(cp->fd,
- "User Host Via Channel Time%s\n",
- full ? " HQueue Receivd Xmitted" : "");
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,"%-8.8s %-8.8s %-8.8s %7d %s",
- p->name,
- p->host,
- p->via ? p->via->name : "",
- p->channel,
- timestring(p->time));
- if(full)
- cp->xmitted += usprintf(cp->fd,"%7d %7d %7d",
- 0, /* always 0 cuz NOS handles the tx-queue */
- p->received,
- p->xmitted);
- cp->xmitted += usputs(cp->fd,"\n");
- }
- }
- }
- #ifdef MAILBOX
- for (i = 0; i < NUMMBX; i++) {
- if((m = Mbox[i]) != NULLMBX) {
- if(m->state == MBX_CMD) {
- if(quick)
- cp->xmitted += usprintf(cp->fd," LocBBS %s\n",m->name);
- else
- cp->xmitted += usprintf(cp->fd,"%-8s LocBBS@%s\n",m->name,Hostname);
- }
- }
- }
- #endif
- cp->xmitted += usputs(cp->fd, "***\n");
- xfree(buffer);
- return;
- }
-
- static void
- h_cmsg_command(cp)
- struct convection *cp;
- {
-
- char *name = getarg(0, 0);
- int channel = atoi(getarg(0, 0));
- char *text = getarg(0, 1);
-
- if (*text) send_msg_to_channel(name, channel, text);
- }
-
- static void
- h_host_command(cp)
- struct convection *cp;
- {
- struct convection *p;
- struct permlink *pp;
-
- char *name = getarg(0,0);
-
- if (!*name) return;
- for (p = convections; p; p = p->next)
- if (!strcmp(p->name, name)) bye_command(p);
- for (pp = permlinks; pp; pp = pp->next)
- if (!strcmp(pp->name, name) && pp->convection && pp->convection != cp)
- bye_command((strcmp(myhostname, name) < 0) ? pp->convection : cp);
- if (cp->type != CT_UNKNOWN) return;
- cp->type = CT_HOST;
- strcpy(cp->name,name); /* already allocated */
- update_permlinks(name, cp);
- cp->xmitted += usprintf(cp->fd, "/\377\200HOST %s\n", myhostname);
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- "/\377\200USER %s %s 0 -1 %d\n", p->name, p->host, p->channel);
- }
- return;
- }
-
- static void
- h_invi_command(cp)
- struct convection *cp;
- {
-
- char *fromname = getarg(0,0);
- char *toname = getarg(0,0);
- int channel = atoi(getarg(0,0));
-
- send_invite_msg(fromname, toname, channel);
- }
-
- static void
- h_umsg_command(cp)
- struct convection *cp;
- {
-
- char *fromname = getarg(0, 0);
- char *toname = getarg(0, 0);
- char *text = getarg(0, 1);
-
- if (*text) send_msg_to_user(fromname, toname, text);
- }
-
- static void
- h_user_command(cp)
- struct convection *cp;
- {
- int oldchannel, newchannel;
- struct convection *p;
-
- char *name = getarg(0, 0);
- char *host = getarg(0, 0);
- getarg(0, 0); /*** ignore this argument, protocol has changed ***/
- oldchannel = atoi(getarg(0, 0));
- newchannel = atoi(getarg(0, 0));
-
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER &&
- p->channel == oldchannel &&
- p->via == cp &&
- !strcmp(p->name, name) &&
- !strcmp(p->host, host)) break;
- if (!p) {
- p = (struct convection *)mxallocw(sizeof(struct convection ));
- p->type = CT_USER;
- sprintf(p->name,"%.79s",name);
- sprintf(p->host,"%.79s",host);
- p->via = cp;
- p->channel = oldchannel;
- p->time = currtime;
- p->next = convections;
- convections = p;
- }
- if ((p->channel = newchannel) < 0) p->type = CT_CLOSED;
- send_user_change_msg(name, host, oldchannel, newchannel);
- }
-
- /* Incoming convers session */
- void
- conv_incom(s,t,p)
- int s;
- void *t;
- void *p;
- {
- int arglen, size;
- struct convection *cp;
- struct permlink *pl;
- char *arg, *ccp, *cccp;
-
- #ifdef MAILBOX
- int len;
- char fsocket[MAXSOCKSIZE];
- #endif
-
- struct cmdtable {
- char *name;
- void (*fnc)();
- int states;
- } cmdtable[] = {
- "?", help_command, CM_USER,
- "bye", bye_command, CM_USER,
- "channel", channel_command, CM_USER,
- "exit", bye_command, CM_USER,
- "help", help_command, CM_USER,
- "invite", invite_command, CM_USER,
- "links", links_command, CM_USER,
- "msg", msg_command, CM_USER,
- "name", name_command, CM_UNKNOWN,
- "quit", bye_command, CM_USER,
- "who", who_command, CM_USER,
- "write", msg_command, CM_USER,
-
- "\377\200cmsg", h_cmsg_command, CM_HOST,
- "\377\200host", h_host_command, CM_UNKNOWN,
- "\377\200invi", h_invi_command, CM_HOST,
- "\377\200umsg", h_umsg_command, CM_HOST,
- "\377\200user", h_user_command, CM_HOST,
-
- 0, 0, 0,
- };
- struct cmdtable *cmdp;
-
- sockowner(s,Curproc); /* We own it now */
- sockmode(s,SOCK_BINARY);
- time(&currtime);
- cp = alloc_connection(s);
-
- #ifdef LZW
- if((int)t == 1)
- lzwinit(s,Lzwbits,Lzwmode);
- #endif
-
- for(pl = permlinks; pl; pl = pl->next)
- if(pl->fd == s) {
- pl->convection = cp;
- if (pl->command != NULLCHAR) usprintf(s, "%s\n", pl->command);
- cp->xmitted += usprintf(s, "/\377\200HOST %s\n", myhostname);
- }
-
- if(pl == NULLPERMLINK) {
- #ifdef MAILBOX
- getpeername(s,fsocket,&len);
- ccp = strxdup(psocket(fsocket));
- if((cccp = strchr(ccp,':')) != NULLCHAR)
- *cccp = '\0';
- if(strcmp(ccp,inet_ntoa(Ip_addr)) != 0)
- usprintf(cp->fd,"\npse login with '/n <call>'\n\n");
- xfree(ccp);
- #else
- usprintf(cp->fd,"\npse login with '/n <call>'\n\n");
- #endif
- }
-
- for (; ; ) {
- loop:
- if(cp->type == CT_CLOSED)
- break;
- if((size = recvline(cp->fd,cp->ibuf,CBUFLEN)) <= 0) {
- break;
- }
- cp->received += size;
- clear_locks();
- cp->locked = 1;
- if((ccp = strpbrk(cp->ibuf,"\r\n")) != NULLCHAR)
- *ccp = '\0';
- if (*cp->ibuf == '/') {
- arglen = strlen(arg = getarg(cp->ibuf + 1, 0));
- for (cmdp = cmdtable; cmdp->name; cmdp++)
- if (!strnicmp(cmdp->name, arg, arglen)) {
- if (cmdp->states & (1 << cp->type))
- (*cmdp->fnc)(cp);
- goto loop;
- }
- if (cp->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- "*** Unknown command '/%s'. Type /HELP for help.\n", arg);
- }
- goto loop;
- }
- if(isprint(*cp->ibuf) != 0 && cp->type == CT_USER)
- send_msg_to_channel(cp->name, cp->channel, cp->ibuf);
- }
- bye_command(cp);
- free_closed_connections();
- return;
- }
-
-
- #endif /* CONVERS */
-